package sindconsole.webapp.controller;

import com.yufeixuan.captcha.Captcha;
import com.yufeixuan.captcha.SpecCaptcha;
import com.yufeixuan.captcha.utils.CaptchaUtil;
import common.annotation.Traced;
import common.exception.BadRequestException;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import sindconsole.auth.bean.UserPrincipal;
import sindconsole.auth.service.AuthService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Slf4j
@RestController
@RequestMapping("/api")
public class ConsoleController {

    @Autowired
    AuthService authService;

    @ExceptionHandler(IncorrectCredentialsException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public @ResponseBody
    String handleException(IncorrectCredentialsException x) {
        log.warn(x.getMessage());
        return x.getMessage();
    }

    @PostMapping("/login")
    @Traced("登入系统")
    public Object login(HttpServletRequest request,
                        @RequestParam("username") String username,
                        @RequestParam("password") String password,
                        @RequestParam("code") String code) {
        if(!CaptchaUtil.ver(code, request)) {
            CaptchaUtil.clear(request);
            throw new BadRequestException("验证码不正确");
        }
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);
        } catch(DisabledAccountException x) {
            throw new DisabledAccountException("该用户已经被冻结");
        } catch(Exception x) {
            log.warn(x.getMessage(), x);
            throw new IncorrectCredentialsException("登录名或密码错误");
        }
        return "OK";
    }

    @GetMapping("/captcha/verify")
    public boolean verify(HttpServletRequest request, @RequestParam("code") String code) throws Exception {
        return CaptchaUtil.ver(code, request);
    }

    @GetMapping("/captcha/image")
    public void captcha(HttpServletRequest request, HttpServletResponse response) throws Exception {
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 3);
        specCaptcha.setCharType(Captcha.TYPE_ONLY_NUMBER);
        request.getSession().setAttribute("captcha_phoenix", specCaptcha.text());
        specCaptcha.out(response.getOutputStream());
    }

    @GetMapping("/subject")
    @RequiresAuthentication
    public String subject(HttpSession session) {
        return ((UserPrincipal)SecurityUtils.getSubject().getPrincipal()).getName();
    }

    @PostMapping("/logout")
    @Traced("登出系统")
    public Object logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "OK";
    }

}
